package com.example.demo.config;

import com.example.demo.filter.JwtAuthFilter;
import com.example.demo.service.CustomUserDetailsService;
import com.example.demo.utils.JwtUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity // 启用方法级安全注解（如@PreAuthorize）
public class SecurityConfig {
    private final JwtUtils jwtUtils;
    private final CustomUserDetailsService userDetailsService;

    public SecurityConfig(JwtUtils jwtUtils, CustomUserDetailsService userDetailsService) {
        this.jwtUtils = jwtUtils;
        this.userDetailsService = userDetailsService;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                // 禁用CSRF（因为使用JWT无状态认证）
                .csrf(AbstractHttpConfigurer::disable)

                // 设置无状态会话（不使用HTTP Session）
                .sessionManagement(session -> session
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                )

                // 配置请求授权规则
                .authorizeHttpRequests(auth -> auth
                        // 公开访问的端点
                        .requestMatchers(
                                "/api/torrents/**",
                                "/api/auth/**",          // 认证相关
                                "/api/announce",         // 公告
                                "/api/error",            // 错误处理
                                "/api/register-admin-init",// 初始管理员注册
                                "/api/usercenter",   //用户中心
                                "/api/torrents/**",       // 种子相关（除下载外）
                                "/api/admin/**"//管理员
                        ).permitAll()

                        // 管理员专属API路径
                        .requestMatchers(
                                "/api/admin/**"          // 兼容旧路径（如有）
                        ).hasRole("ADMIN")

                        // 需要认证但无特殊角色要求的路径
                        .requestMatchers(
                                "/api/user/**"         // 用户相关
//                                "/torrents/**"       // 种子相关（除下载外）
                        ).authenticated()

                        .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() // 放行所有OPTIONS请求
                        .anyRequest().authenticated()
                )

                // 添加JWT认证过滤器
                .addFilterBefore(
                        new JwtAuthFilter(jwtUtils, userDetailsService),
                        UsernamePasswordAuthenticationFilter.class
                );

        return http.build();
    }

    // 密码编码器（BCrypt强哈希）
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    // 认证管理器
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
        return authConfig.getAuthenticationManager();
    }

    // 自定义认证提供者
    @Bean
    public AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService);
        provider.setPasswordEncoder(passwordEncoder());
        return provider;
    }
}